package com.kye.express.business.order.order_address;

import com.kye.express.contract.base.BasePresenter;
import com.kye.express.contract.base.view.ErrorView;
import com.kye.express.contract.base.view.IView;
import com.kye.express.contract.base.view.LoadingView;
import com.kye.model.UserSession;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.order.OrderAddresses;
import com.kye.model.bean.order.request.RequestOrderAddresses;
import com.kye.model.bean.user.User;
import com.kye.model.datasource.OrderDataSource;

import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;

public interface AddressListContract {
    interface AddressListView extends IView, LoadingView, ErrorView {

        void onAddress(List<Object> objects);
    }

    class AddressListPresenter extends BasePresenter<AddressListView> {

        private OrderDataSource mOrderDataSource;

        @Override
        public void bind(AddressListView view) {
            super.bind(view);
            mOrderDataSource = new OrderDataSource();
        }

        public void getAddresses(String guid) {
            UserSession.getInstance()
                    .getUserForRx()
                    .firstOrError()
                    .flatMap(new Function<User, SingleSource<OpenApiResult<List<OrderAddresses>>>>() {
                        @Override
                        public SingleSource<OpenApiResult<List<OrderAddresses>>> apply(User user) throws Exception {
                            return mOrderDataSource.getAddresses(new RequestOrderAddresses(user.getPhone(), user.getCustomCode()));
                        }
                    })
                    .map(new Function<OpenApiResult<List<OrderAddresses>>, List<OrderAddresses>>() {
                        @Override
                        public List<OrderAddresses> apply(OpenApiResult<List<OrderAddresses>> openApiResult) throws Exception {
                            return openApiResult.getData();
                        }
                    })
                    .toObservable()
                    .flatMap(new Function<List<OrderAddresses>, ObservableSource<OrderAddresses>>() {
                        @Override
                        public ObservableSource<OrderAddresses> apply(List<OrderAddresses> orderAddresses) throws Exception {
                            return Observable.fromIterable(orderAddresses);
                        }
                    })
                    .flatMap(new Function<OrderAddresses, ObservableSource<?>>() {
                        @Override
                        public ObservableSource<?> apply(OrderAddresses orderAddresses) throws Exception {
                            return Observable.merge(
                                    Observable.just(orderAddresses),
                                    Observable.fromIterable(orderAddresses.getAddresses()).map(new Function<OrderAddresses.Address, AddressViewBinder.AddressViewBean>() {
                                        @Override
                                        public AddressViewBinder.AddressViewBean apply(OrderAddresses.Address address) throws Exception {
                                            return new AddressViewBinder.AddressViewBean(address, guid.equals(address.getGuid()));
                                        }
                                    })
                            );
                        }
                    })
                    .toList()
                    .compose(getView().bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnSubscribe(new Consumer<Disposable>() {
                        @Override
                        public void accept(Disposable disposable) throws Exception {
                            getView().onLoading();
                        }
                    })
                    .doAfterTerminate(new Action() {
                        @Override
                        public void run() throws Exception {
                            getView().onLoaded();
                        }
                    })
                    .subscribe(new Consumer<List<Object>>() {
                        @Override
                        public void accept(List<Object> objects) throws Exception {
                            getView().onAddress(objects);
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            getView().onError();
                        }
                    });
        }
    }
}
